package chapter6;

import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;

public class Ex12 extends Applet {
  public static void main(String[] args) {
    new MainFrame(new Ex12(), 640, 480);
  }

  public void init() {
    // create canvas
    GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
    Canvas3D cv = new Canvas3D(gc);
    setLayout(new BorderLayout());
    add(cv, BorderLayout.CENTER);
    BranchGroup bg = createSceneGraph();
    bg.compile();
    SimpleUniverse su = new SimpleUniverse(cv);
    su.getViewingPlatform().setNominalViewingTransform();
    su.addBranchGraph(bg);
  }

  private BranchGroup createSceneGraph() {
    BranchGroup root = new BranchGroup();
    TransformGroup spin = new TransformGroup();
    spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    root.addChild(spin);
    //object
    Appearance ap = new Appearance();
    ColoringAttributes ca = new ColoringAttributes();
    ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
    ap.setColoringAttributes(ca);
    Shape3D shape = new Shape3D(new ColorOctahedron(), ap);
    //rotating object
    Transform3D tr = new Transform3D();
    tr.setScale(0.25);
    TransformGroup tg = new TransformGroup(tr);
    spin.addChild(tg);
    tg.addChild(shape);
    Alpha alpha = new Alpha(-1, 4000);
    RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
    BoundingSphere bounds = new BoundingSphere();
    rotator.setSchedulingBounds(bounds);
    spin.addChild(rotator);
    return root;
  }
}

class ColorOctahedron extends IndexedTriangleArray {
  public ColorOctahedron() {
    super(8, GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR_3, 24);
    setCoordinate(0, new Point3f(0,0,1));
    setCoordinate(1, new Point3f(-1,0,0));
    setCoordinate(2, new Point3f(0,-1,0));
    setCoordinate(3, new Point3f(1,0,0));
    setCoordinate(4, new Point3f(0,1,0));
    setCoordinate(5, new Point3f(0,0,-1));
    int[] vertInd = {0,1,2,0,2,3,0,3,4,0,4,1,
    5,1,4,5,4,3,5,3,2,5,2,1};
    setCoordinateIndices(0, vertInd);
    float d = 1f/(float)Math.sqrt(3);
    setNormal(0, new Vector3f(-d,-d,d));
    setNormal(1, new Vector3f(d,-d,d));
    setNormal(2, new Vector3f(d,d,d));
    setNormal(3, new Vector3f(-d,d,d));
    setNormal(4, new Vector3f(-d,d,-d));
    setNormal(5, new Vector3f(d,d,-d));
    setNormal(6, new Vector3f(d,-d,-d));
    setNormal(7, new Vector3f(-d,-d,-d));
    int[] normInd = {0,0,0,1,1,1,2,2,2,3,3,3,
    4,4,4,5,5,5,6,6,6,7,7,7};
    setNormalIndices(0,normInd);
    setColor(0, new Color3f(1,0,0));
    setColor(1, new Color3f(0,1,0));
    setColor(2, new Color3f(0,0,1));
    setColor(3, new Color3f(1,0,1));
    setColor(4, new Color3f(1,1,0));
    setColor(5, new Color3f(0,1,1));
    this.setColorIndices(0, vertInd);
  }  
}